<template>
  <div id="app">
    <div class="container">
      <div class="header">
        <div class="app-title">AI图像生成</div>
      </div>

      <!-- 全局错误提示 -->
      <div v-if="globalError" class="global-error" @click="globalError = ''">
        {{ globalError }} <span style="margin-left:8px">(点击关闭)</span>
      </div>

      <div class="content">
        <!-- 谷歌 ImageFX 区域 -->
        <div class="generator-section">
          <div class="section-title">
            <div class="section-icon google-icon">G</div>
            谷歌 ImageFX
          </div>

          <div v-if="googleError" class="error-message">{{ googleError }}</div>

          <div class="slide-container">
            <div class="slide-wrapper" :style="{ transform: `translateX(-${googleCurrentSlide * 100}%)` }">
              <div class="slide-item" v-for="(group, index) in googleImageGroups" :key="index">
                <!-- 单张图片展示区域 -->
                <div class="single-image-display">
                  <div class="image-item2"
                       @click="openImageOverlay(group[googleCurrentImageIndex])"
                       :style="{'--aspect-ratio': getAspectRatio()}">
                    <!-- 添加图片对象存在检查 -->
                    <div v-if="!group[googleCurrentImageIndex]" class="image-placeholder">图片加载中...</div>
                    <div v-else-if="group[googleCurrentImageIndex].status === 'placeholder'" class="image-placeholder">暂无图片</div>
                    <div v-else-if="group[googleCurrentImageIndex].status === 'generating'" class="image-placeholder image-generating">
                      <div class="loading-spinner"></div>
                      <div style="margin-top: 8px;">生成中...</div>
                    </div>
                    <div v-else-if="group[googleCurrentImageIndex].status === 'error'" class="image-placeholder error-state">
                      {{ group[googleCurrentImageIndex].msg || '生成失败' }}
                    </div>
                    <!-- 缓存图片占位符 -->
                    <div v-else-if="group[googleCurrentImageIndex].status === 'completed' && group[googleCurrentImageIndex].url === '[cached]'"
                         class="image-placeholder">
                      缓存图片
                    </div>
                    <img v-else-if="group[googleCurrentImageIndex].status === 'completed'"
                         :src="group[googleCurrentImageIndex].url"
                         :alt="group[googleCurrentImageIndex].prompt"
                         @error="handleImageError(group[googleCurrentImageIndex])" />
                  </div>

                  <!-- 组内图片切换按钮 -->
                  <div class="image-nav">
                    <button class="image-nav-btn" :disabled="googleCurrentImageIndex === 0" @click="googlePrevImage">←</button>
                    <div class="image-nav-info">{{ googleCurrentImageIndex + 1 }}/4</div>
                    <button class="image-nav-btn" :disabled="googleCurrentImageIndex === 3" @click="googleNextImage">→</button>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- 提交次数分页 -->
          <div class="pagination" v-if="googleImageGroups.length > 0">
            <button class="pagination-btn" :disabled="googleCurrentSlide === 0" @click="googlePrevSlide">←</button>
            <div class="pagination-info">{{ googleCurrentSlide + 1 }}/{{ googleImageGroups.length }}</div>
            <button class="pagination-btn" :disabled="googleCurrentSlide === googleImageGroups.length - 1" @click="googleNextSlide">→</button>
          </div>
        </div>

        <!-- 火山引擎区域 -->
        <div class="generator-section">
          <div class="section-title">
            <div class="section-icon volcano-icon">火</div>
            宇宙火山引擎
          </div>

          <div v-if="volcanoError" class="error-message">{{ volcanoError }}</div>

          <div class="slide-container">
            <div class="slide-wrapper" :style="{ transform: `translateX(-${volcanoCurrentSlide * 100}%)` }">
              <div class="slide-item" v-for="(group, index) in volcanoImageGroups" :key="index">
                <!-- 单张图片展示区域 -->
                <div class="single-image-display">
                  <div class="image-item"
                       @click="openImageOverlay(group[volcanoCurrentImageIndex])"
                       :style="{'--aspect-ratio': getAspectRatio()}">
                    <!-- 添加图片对象存在检查 -->
                    <div v-if="!group[volcanoCurrentImageIndex]" class="image-placeholder">图片加载中...</div>
                    <div v-else-if="group[volcanoCurrentImageIndex].status === 'placeholder'" class="image-placeholder">暂无图片</div>
                    <div v-else-if="group[volcanoCurrentImageIndex].status === 'generating'" class="image-placeholder image-generating">
                      <div class="loading-spinner"></div>
                      <div style="margin-top: 8px;">生成中...</div>
                    </div>
                    <div v-else-if="group[volcanoCurrentImageIndex].status === 'error'" class="image-placeholder error-state">
                      {{ group[volcanoCurrentImageIndex].msg || '生成失败' }}
                    </div>
                    <!-- 缓存图片占位符 -->
                    <div v-else-if="group[volcanoCurrentImageIndex].status === 'completed' && group[volcanoCurrentImageIndex].url === '[cached]'"
                         class="image-placeholder">
                      缓存图片
                    </div>
                    <img v-else-if="group[volcanoCurrentImageIndex].status === 'completed'"
                         :src="group[volcanoCurrentImageIndex].url"
                         :alt="group[volcanoCurrentImageIndex].prompt"
                         @error="handleImageError(group[volcanoCurrentImageIndex])" />
                  </div>

                  <!-- 组内图片切换按钮 -->
                  <div class="image-nav">
                    <button class="image-nav-btn" :disabled="volcanoCurrentImageIndex === 0" @click="volcanoPrevImage">←</button>
                    <div class="image-nav-info">{{ volcanoCurrentImageIndex + 1 }}/4</div>
                    <button class="image-nav-btn" :disabled="volcanoCurrentImageIndex === 3" @click="volcanoNextImage">→</button>
                  </div>
                </div>
              </div>
            </div>
          </div>

          <!-- 提交次数分页 -->
          <div class="pagination" v-if="volcanoImageGroups.length > 0">
            <button class="pagination-btn" :disabled="volcanoCurrentSlide === 0" @click="volcanoPrevSlide">←</button>
            <div class="pagination-info">{{ volcanoCurrentSlide + 1 }}/{{ volcanoImageGroups.length }}</div>
            <button class="pagination-btn" :disabled="volcanoCurrentSlide === volcanoImageGroups.length - 1" @click="volcanoNextSlide">→</button>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="input-section">
        <div class="input-container">
          <div class="input-group">
            <div class="input-wrapper">
              <input
                  type="text"
                  class="text-input"
                  placeholder="请输入描述文字（例如：一只红色的狐狸在雪地里）"
                  v-model="inputText"
                  @keyup.enter="generateImages"
              />
              <button class="submit-btn" @click="generateImages" :disabled="isGenerating || !inputText.trim()">
                {{ isGenerating ? '生成中...' : '提交' }}
              </button>
            </div>
          </div>

          <div class="ratio-selector">
            <span class="ratio-label">比例:</span>
            <button
                class="ratio-btn"
                v-for="ratio in ratios"
                :key="ratio.value"
                :class="{ active: selectedRatio === ratio.value }"
                @click="selectedRatio = ratio.value"
            >
              {{ ratio.label }}
            </button>
          </div>
        </div>
      </div>

      <!-- 图片预览遮罩层 -->
      <div class="image-overlay" :class="{ show: showImageOverlay }" @click="closeImageOverlay">
        <img v-if="selectedImage && selectedImage.url !== '[cached]'" :src="selectedImage.url" :alt="selectedImage.prompt" class="overlay-image" />
        <!-- 缓存图片预览时显示提示 -->
        <div v-if="selectedImage && selectedImage.url === '[cached]'" class="overlay-placeholder">
          缓存图片无法预览
        </div>
        <!-- 修复：添加v-前缀并修正表达式 -->
        <div v-else-if="!selectedImage" class="overlay-placeholder">
          图片加载失败
        </div>
        <button class="close-btn" @click.stop="closeImageOverlay">×</button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { generateImageFX } from "./api/generateImageFX";

// 状态管理
const inputText = ref('');
const selectedRatio = ref('1:1');
const isGenerating = ref(false);
const showImageOverlay = ref(false);
const selectedImage = ref(null);
const googleCurrentSlide = ref(0);
const volcanoCurrentSlide = ref(0);
const googleCurrentImageIndex = ref(0); // 当前组内图片索引
const volcanoCurrentImageIndex = ref(0); // 当前组内图片索引
const googleError = ref('');
const volcanoError = ref('');
const globalError = ref(''); // 全局错误提示

// 比例选项
const ratios = [
  { label: '1:1', value: '1:1' },
  { label: '3:4', value: '3:4' },
  { label: '4:3', value: '4:3' },
  { label: '16:9', value: '16:9' },
  { label: '9:16', value: '9:16' }
];

// 初始化图片组（空数组）
const googleImageGroups = ref([]);
const volcanoImageGroups = ref([]);
const MAX_HISTORY = 3; // 限制最大历史记录组数（减少缓存体积）

// 初始化时加载缓存
onMounted(() => {
  loadFromCache();
});

// 计算图片比例（用于CSS变量）
const getAspectRatio = () => {
  const [width, height] = selectedRatio.value.split(':').map(Number);
  return width / height;
};

// 图片加载失败处理
const handleImageError = (image) => {
  if (image) { // 添加检查，确保图片对象存在
    image.status = 'error';
    image.msg = '图片加载失败';
  }
};

// 生成图片主函数
const generateImages = async () => {
  const prompt = inputText.value.trim();
  if (!prompt || isGenerating.value) return;

  // 状态初始化
  isGenerating.value = true;
  googleError.value = '';
  volcanoError.value = '';
  globalError.value = '';

  // 重置图片索引为第一张
  googleCurrentImageIndex.value = 0;
  volcanoCurrentImageIndex.value = 0;

  // 创建"生成中"的图片组（每组4张）
  const generatingItem = { status: 'generating', url: '', prompt, msg: '' };
  const generatingGroup = Array(4).fill().map(() => ({ ...generatingItem }));

  // 追加新组（限制历史数量）
  googleImageGroups.value.push([...generatingGroup]);
  volcanoImageGroups.value.push([...generatingGroup]);

  // 超过最大历史记录则移除最早的组
  if (googleImageGroups.value.length > MAX_HISTORY) {
    googleImageGroups.value.shift();
  }
  if (volcanoImageGroups.value.length > MAX_HISTORY) {
    volcanoImageGroups.value.shift();
  }

  // 切换到最新页
  googleCurrentSlide.value = googleImageGroups.value.length - 1;
  volcanoCurrentSlide.value = volcanoImageGroups.value.length - 1;

  try {
    const results = await Promise.allSettled([
      // 谷歌接口调用（处理403错误）
      (async () => {
        try {
          const images = await generateImageFX(prompt);
          return images.map(img => ({
            status: 'completed',
            url: img.imageUrl,
            prompt: img.prompt || prompt,
            msg: ''
          }));
        } catch (err) {
          // 403错误特殊处理
          if (err.response && err.response.status === 403) {
            throw new Error('谷歌API权限不足：请检查token有效性或配额是否充足');
          } else {
            throw new Error(`谷歌生成失败：${err.message || '未知错误'}`);
          }
        }
      })(),

      // 火山接口调用（处理JSON解析错误）
      (async () => {
        const group = [];
        for (let i = 0; i < 4; i++) {
          try {
            const res = await fetch("https://dev-ai.alterme.cn/api/volcengine/textToImage", {
              method: "POST",
              headers: { "Content-Type": "application/json" },
              body: JSON.stringify({
                req_key: "high_aes_general_v30l_zt2i",
                prompt: prompt,
                aspect_ratio: selectedRatio.value
              })
            });

            // 先检查响应状态
            if (!res.ok) {
              const errorText = await res.text().catch(() => '未知错误');
              throw new Error(`接口状态错误(${res.status})：${errorText.slice(0, 30)}`);
            }

            // 解析JSON（防止格式错误）
            let data;
            const responseText = await res.text(); // 先转为文本
            try {
              data = JSON.parse(responseText); // 再解析JSON
            } catch (jsonErr) {
              throw new Error(`数据格式错误：${jsonErr.message}（响应：${responseText.slice(0, 30)}）`);
            }

            const base64 = data.data?.binary_data_base64?.[0];
            if (base64) {
              group.push({
                status: 'completed',
                url: `data:image/png;base64,${base64}`,
                prompt,
                msg: ''
              });
            } else {
              group.push({
                status: 'error',
                url: '',
                prompt,
                msg: '接口未返回图片数据'
              });
            }
          } catch (err) {
            // 记录单张图片错误信息
            group.push({
              status: 'error',
              url: '',
              prompt,
              msg: `第${i+1}张：${err.message.slice(0, 20)}`
            });
          }
        }
        return group;
      })()
    ]);

    // 处理谷歌结果
    if (results[0].status === 'fulfilled') {
      googleImageGroups.value[googleCurrentSlide.value] = results[0].value;
    } else {
      googleError.value = results[0].reason.message;
      // 替换为错误状态并携带信息
      googleImageGroups.value[googleCurrentSlide.value] = Array(4).fill().map(() => ({
        status: 'error',
        url: '',
        prompt,
        msg: results[0].reason.message.slice(0, 20)
      }));
    }

    // 处理火山结果
    if (results[1].status === 'fulfilled') {
      volcanoImageGroups.value[volcanoCurrentSlide.value] = results[1].value;
    } else {
      volcanoError.value = results[1].reason.message;
      volcanoImageGroups.value[volcanoCurrentSlide.value] = Array(4).fill().map(() => ({
        status: 'error',
        url: '',
        prompt,
        msg: results[1].reason.message.slice(0, 20)
      }));
    }

    // 保存缓存（处理配额超限）
    try {
      saveToCache();
    } catch (cacheErr) {
      // 缓存超限则清除旧缓存
      globalError.value = '缓存空间不足，已自动清理旧数据';
      localStorage.removeItem('imageHistory');
      // 尝试重新保存
      try {
        saveToCache();
      } catch (e) {
        console.warn('清理后仍无法保存缓存：', e);
      }
    }

  } catch (err) {
    console.error('生成异常：', err);
    globalError.value = `系统错误：${err.message}`;
  } finally {
    isGenerating.value = false;
    inputText.value = ''; // 清空输入框
  }
};

// 缓存管理（减少存储体积）
const saveToCache = () => {
  // 缓存中只保存关键信息，不保存完整base64（大幅减少体积）
  const cacheData = {
    google: googleImageGroups.value.map(group =>
        group.map(img => ({
          ...img,
          url: img.status === 'completed' ? '[cached]' : img.url // 替换base64为缓存标记
        }))
    ),
    volcano: volcanoImageGroups.value.map(group =>
        group.map(img => ({
          ...img,
          url: img.status === 'completed' ? '[cached]' : img.url // 替换base64为缓存标记
        }))
    ),
    // 保存当前索引状态
    googleCurrentSlide: googleCurrentSlide.value,
    volcanoCurrentSlide: volcanoCurrentSlide.value,
    googleCurrentImageIndex: googleCurrentImageIndex.value,
    volcanoCurrentImageIndex: volcanoCurrentImageIndex.value
  };
  localStorage.setItem('imageHistory', JSON.stringify(cacheData));
};

// 加载缓存（兼容旧数据）
const loadFromCache = () => {
  try {
    const cached = localStorage.getItem('imageHistory');
    if (cached) {
      const { google, volcano, googleCurrentSlide: gSlide, volcanoCurrentSlide: vSlide,
        googleCurrentImageIndex: gIndex, volcanoCurrentImageIndex: vIndex } = JSON.parse(cached);
      if (Array.isArray(google)) googleImageGroups.value = google;
      if (Array.isArray(volcano)) volcanoImageGroups.value = volcano;
      // 恢复索引状态
      if (typeof gSlide === 'number') googleCurrentSlide.value = gSlide;
      if (typeof vSlide === 'number') volcanoCurrentSlide.value = vSlide;
      if (typeof gIndex === 'number') googleCurrentImageIndex.value = gIndex;
      if (typeof vIndex === 'number') volcanoCurrentImageIndex.value = vIndex;
    }
  } catch (err) {
    console.error('加载缓存失败：', err);
    localStorage.removeItem('imageHistory'); // 清除损坏的缓存
  }
};

// 图片预览相关
const openImageOverlay = (image) => {
  if (image && image.status === 'completed') { // 添加检查，确保图片存在且状态正确
    selectedImage.value = image;
    showImageOverlay.value = true;
  }
};

const closeImageOverlay = () => {
  showImageOverlay.value = false;
  selectedImage.value = null;
};

// 组间分页控制（提交次数）
const googlePrevSlide = () => {
  if (googleCurrentSlide.value > 0) {
    googleCurrentSlide.value--;
    googleCurrentImageIndex.value = 0; // 重置为第一张图片
  }
};

const googleNextSlide = () => {
  if (googleCurrentSlide.value < googleImageGroups.value.length - 1) {
    googleCurrentSlide.value++;
    googleCurrentImageIndex.value = 0; // 重置为第一张图片
  }
};

const volcanoPrevSlide = () => {
  if (volcanoCurrentSlide.value > 0) {
    volcanoCurrentSlide.value--;
    volcanoCurrentImageIndex.value = 0; // 重置为第一张图片
  }
};

const volcanoNextSlide = () => {
  if (volcanoCurrentSlide.value < volcanoImageGroups.value.length - 1) {
    volcanoCurrentSlide.value++;
    volcanoCurrentImageIndex.value = 0; // 重置为第一张图片
  }
};

// 组内图片切换控制
const googlePrevImage = () => {
  if (googleCurrentImageIndex.value > 0) {
    googleCurrentImageIndex.value--;
  }
};

const googleNextImage = () => {
  if (googleCurrentImageIndex.value < 3) {
    googleCurrentImageIndex.value++;
  }
};

const volcanoPrevImage = () => {
  if (volcanoCurrentImageIndex.value > 0) {
    volcanoCurrentImageIndex.value--;
  }
};

const volcanoNextImage = () => {
  if (volcanoCurrentImageIndex.value < 3) {
    volcanoCurrentImageIndex.value++;
  }
};
</script>

<style scoped>
/* 全局错误样式 */
.global-error {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  background: #ff4444;
  color: white;
  padding: 10px 20px;
  border-radius: 4px;
  z-index: 1001;
  font-size: 14px;
  cursor: pointer;
  max-width: 90%;
  text-align: center;
}

/* 基础样式 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* 容器样式 */
.container {
  min-height: 100vh;
  padding: 15px 15px 120px;
  background-color: #f5f7fa;
  max-width: 100vw; /* 防止超出屏幕宽度 */
  width: 100%; /* 确保占满屏幕宽度 */
  overflow-x: hidden;
  margin: 0 auto; /* 居中显示 */
}

.header {
  text-align: center;
  margin-bottom: 20px;
}

.app-title {
  font-size: 24px;
  font-weight: bold;
  color: #2c3e50;
}

/* 生成区域样式 */
.content {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.generator-section {
  background: white;
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  width: 100%; /* 适应容器宽度 */
}

.section-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 15px;
  color: #2c3e50;
}

.section-icon {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: bold;
  color: white;
}

.google-icon {
  background: linear-gradient(45deg, #4285f4, #34a853);
}

.volcano-icon {
  background: linear-gradient(45deg, #ff6b6b, #ff8e53);
}

.error-message {
  background: #f8d7da;
  color: #721c24;
  padding: 10px;
  border-radius: 6px;
  margin-bottom: 15px;
  font-size: 14px;
}

/* 图片轮播样式 */
.slide-container {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: 8px;
}

.slide-wrapper {
  display: flex;
  transition: transform 0.3s ease;
  height: 100%;
}

.slide-item {
  min-width: 100%;
  display: flex;
  justify-content: center;
  padding: 5px 0;
}

/* 单张图片展示区域 */
.single-image-display {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  width: 100%;
  max-width: 400px; /* 限制最大宽度 */
}

.image-item {
  width: 100%;
  aspect-ratio: var(--aspect-ratio, 1);
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.2s ease;
  background: #f8f9fa;
  border: 1px solid #e9ecef;
}

.image-item2 {
  width: 100%;
  aspect-ratio: var(--aspect-ratio, 1 / 2);
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.2s ease;
  background: #f8f9fa;
  border: 1px solid #e9ecef;
}

.image-item:hover {
  transform: scale(1.02);
}

.image-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #6c757d;
  font-size: 14px;
  background: #f8f9fa;
  text-align: center;
  padding: 0 5px;
}

.image-generating {
  background: linear-gradient(45deg, #e3f2fd, #f3e5f5);
  flex-direction: column;
}

.error-state {
  color: #dc3545;
  font-weight: 500;
  font-size: 12px;
}

.loading-spinner {
  width: 20px;
  height: 20px;
  border: 2px solid #e3f2fd;
  border-top: 2px solid #2196f3;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 组内图片导航样式 */
.image-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
}

.image-nav-btn {
  background: #28a745;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 6px 12px;
  cursor: pointer;
  font-size: 14px;
  transition: background 0.2s ease;
}

.image-nav-btn:hover:not(:disabled) {
  background: #218838;
}

.image-nav-btn:disabled {
  background: #6c757d;
  cursor: not-allowed;
}

.image-nav-info {
  font-size: 14px;
  color: #28a745;
  font-weight: 500;
}

/* 分页样式 */
.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 15px;
  margin-top: 15px;
}

.pagination-btn {
  background: #007bff;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 6px 12px;
  cursor: pointer;
  font-size: 14px;
  transition: background 0.2s ease;
}

.pagination-btn:hover:not(:disabled) {
  background: #0056b3;
}

.pagination-btn:disabled {
  background: #6c757d;
  cursor: not-allowed;
}

.pagination-info {
  font-size: 14px;
  color: #6c757d;
}

/* 输入区域样式 */
.input-section {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background-color: #fff;
  padding: 12px;
  box-shadow: 0 -2px 12px 0 rgba(0, 0, 0, 0.1);
  width: 100%; /* 确保占满屏幕宽度 */
}

.input-container {
  max-width: 100%; /* 适应屏幕宽度 */
  padding: 0 10px; /* 增加内边距，避免贴边 */
  margin: 0 auto;
}

.input-group {
  margin-bottom: 10px;
}

.input-wrapper {
  display: flex;
  gap: 8px;
  width: 100%; /* 占满容器宽度 */
}

.text-input {
  flex: 1;
  padding: 10px 12px;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 14px;
  outline: none;
  transition: border-color 0.2s ease;
  min-width: 0; /* 允许输入框缩小 */
}

.text-input:focus {
  border-color: #007bff;
}

.submit-btn {
  background: #007bff;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 10px 20px;
  cursor: pointer;
  font-size: 14px;
  transition: background 0.2s ease;
  white-space: nowrap; /* 防止按钮文字换行 */
}

.submit-btn:hover:not(:disabled) {
  background: #0056b3;
}

.submit-btn:disabled {
  background: #6c757d;
  cursor: not-allowed;
}

.ratio-selector {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap; /* 允许换行 */
  padding: 5px 0;
}

.ratio-label {
  font-size: 14px;
  color: #6c757d;
}

.ratio-btn {
  background: #f8f9fa;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 4px 8px;
  cursor: pointer;
  font-size: 12px;
  transition: all 0.2s ease;
  white-space: nowrap;
}

.ratio-btn.active {
  background: #007bff;
  color: white;
  border-color: #007bff;
}

/* 预览层样式 */
.image-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  opacity: 0;
  visibility: hidden;
  transition: all 0.3s ease;
}

.image-overlay.show {
  opacity: 1;
  visibility: visible;
}

.overlay-image {
  max-width: 90%;
  max-height: 90%;
  border-radius: 8px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
}

.overlay-placeholder {
  color: white;
  font-size: 18px;
  text-align: center;
  padding: 20px;
}

.close-btn {
  position: absolute;
  top: 20px;
  right: 20px;
  background: rgba(255, 255, 255, 0.2);
  color: white;
  border: none;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  font-size: 20px;
  cursor: pointer;
  transition: background 0.2s ease;
}

.close-btn:hover {
  background: rgba(255, 255, 255, 0.3);
}

/* 响应式调整 - 适配移动设备 */
@media (max-width: 768px) {
  .single-image-display {
    max-width: 100%; /* 占满屏幕宽度 */
  }

  .section-title {
    font-size: 16px; /* 缩小标题字体 */
  }

  .app-title {
    font-size: 20px; /* 缩小应用标题 */
  }

  .image-nav-btn,
  .pagination-btn {
    padding: 5px 10px; /* 缩小按钮尺寸 */
    font-size: 13px;
  }

  .text-input,
  .submit-btn {
    padding: 8px 10px; /* 缩小输入框和按钮 */
    font-size: 13px;
  }

  .ratio-btn {
    padding: 3px 6px; /* 缩小比例选择按钮 */
    font-size: 11px;
  }

  .slide-container {
    min-height: 200px; /* 调整最小高度，适应手机屏幕 */
  }
}

/* 适配小屏手机 */
@media (max-width: 375px) {
  .container {
    padding: 10px 10px 100px; /* 减少内边距 */
  }

  .generator-section {
    padding: 15px; /* 减少卡片内边距 */
  }

  .input-section {
    padding: 8px; /* 减少底部输入区 padding */
  }

  .image-nav,
  .pagination {
    gap: 8px; /* 减少按钮间距 */
  }
}
</style>